/*
 * @Author: malgee
 * @Date: 2025-04-18 11:25:35
 * @LastEditors: maling
 * @LastEditTime: 2025-04-24 16:59:34
 * @FilePath: /vue3-ts-cms/src/service/request/index.ts
 * @Description:
 *
 */

import axios, {
  type AxiosInstance,
  type AxiosResponse,
  type InternalAxiosRequestConfig
} from 'axios'
import { MGInterceptors, MGRequestConfig, MGDataType } from './type'
import { mockHttp, isMock } from '@/mock'

class AxiosHttp {
  instance: AxiosInstance
  interceptors?: MGInterceptors
  showLoading?: boolean
  loading?: any

  constructor(config: MGRequestConfig) {
    // 1. 创建axios实例
    this.instance = axios.create(config)
    this.interceptors = config.interceptors
    this.showLoading = config.showLoading ?? true

    // 2.使用初始拦截器
    this.instance.interceptors.request.use(
      this.interceptors?.requestInterceptor as (
        config: InternalAxiosRequestConfig
      ) => InternalAxiosRequestConfig,
      this.interceptors?.requestInterceptorCatch
    )
    this.instance.interceptors.response.use(
      this.interceptors?.responseInterceptor as (
        response: AxiosResponse
      ) => AxiosResponse,
      this.interceptors?.responseInterceptorCatch
    )

    // 3. 使用全局拦截器添加所有实例拦截器
    this.instance.interceptors.request.use(
      (config) => {
        console.log('全部-请求拦截器')
        return config
      },
      (error) => {
        console.log('全部-请求拦截器-失败')
        return error
      }
    )

    this.instance.interceptors.response.use(
      (response) => {
        console.log('全部-响应拦截器')
        return response
      },
      (error) => {
        console.log('全部-响应拦截器-失败')
        return error
      }
    )
  }

  request<T = any>(config: MGRequestConfig): Promise<MGDataType<T>> {
    if (isMock) {
      return new Promise((resolve) => {
        mockHttp.getData(config).then((res) => {
          resolve({data: res, config, success: true} as MGDataType<T>)
        })
      })
    }
    return new Promise((resolve, reject) => {
      // 单个请求拦截 / 初始全部配置
      if (config.interceptors?.requestInterceptor) {
        config = config.interceptors.requestInterceptor(config)
      }

      this.instance
        .request(config)
        .then((response) => {
          // 单个响应拦截
          if (config.interceptors?.responseInterceptor) {
            response = config.interceptors.responseInterceptor(response)
          }
          if (response.status === 200 && response.data) {
            const data = response.data
            data.config = response.config
            data.headers = response.headers
            data.request = response.request
            data.success = response.status === 200
            resolve(data as MGDataType<T>)
          } else {
            reject(
              new Error('Request failed with status code: ' + response.status)
            )
          }
        })
        .catch((error) => {
          // 单个响应拦截失败
          if (config.interceptors?.responseInterceptorCatch) {
            error = config.interceptors.responseInterceptorCatch(error)
          }
          reject(error)
        })
    })
  }

  get<T = any>(config: MGRequestConfig): Promise<MGDataType<T>> {
    return this.request({
      ...config,
      method: 'get'
    })
  }

  post<T = any>(config: MGRequestConfig): Promise<MGDataType<T>> {
    return this.request({
      ...config,
      method: 'post'
    })
  }

  put<T = any>(config: MGRequestConfig): Promise<MGDataType<T>> {
    return this.request({
      ...config,
      method: 'put'
    })
  }

  delete<T = any>(config: MGRequestConfig): Promise<MGDataType<T>> {
    return this.request({
      ...config,
      method: 'delete'
    })
  }

  patch<T = any>(config: MGRequestConfig): Promise<MGDataType<T>> {
    return this.request({
      ...config,
      method: 'patch'
    })
  }
}
export default AxiosHttp
